#!/usr/bin/python2

'''
Created on Dec 24, 2011

@author: u
'''

import sys
import client
import logging
import asyncore
import time
import world
import uuid
import euclid
import config

last_update_time = 0.

def get_picture(picture_id):    
    pictures = [{"file" : "tableaux/Picasso-FemmeQuiPleure-512x512.jpg", "height" : 0.5, "width" : 0.608},
                {"file" : "tableaux/Vinci-Joconde-512x128.jpg", "height" : 0.77, "width" : 0.53},
                {"file" : "tableaux/Altdorfer-Bataille-256x512.jpg", "height" : 1.584, "width" : 1.2},
                {"file" : "tableaux/Arcimboldo-Vertumne-1024x1024.jpg", "height" : 1.3, "width" : 0.974}]
    
    return pictures[picture_id % len(pictures)]

def get_picture_message(picture_id):   
    messages = ["Femme qui pleure", "La Joconde", "Bataille", "Vertume"]
    return messages[picture_id % len(messages)]

def get_picture_pos(block_coord, picture_id):
    """
    calculates the positions of the pictures in the scene from
    from the id
    """
    
    positions = []
    for i in [11., 14.]:
        for j in [11., 14.]:
            positions.append((i, j))

    block_pos = world.block_to_world(block_coord)
    position = positions[picture_id % len(positions)]
    return position[0] + block_pos[0], world.default_height, position[1] + block_pos[1]

def get_picture_angle(picture_id):    
    angles = [45., 135., -45., 225.]

    return angles[picture_id % len(angles)]
    
class Context:
    def __init__(self):        
        try:
            block_x, block_y, picture_id = sys.argv[1:]
            block_x, block_y, picture_id = int(block_x), int(block_y), int(picture_id)
        except ValueError:
            print("Usage : picture bx by picture_id")
            raise
        
        self.picture_info = get_picture(picture_id)
        self.message = get_picture_message(picture_id)
        self.position = get_picture_pos((block_x, block_y), picture_id)
        self.angle = get_picture_angle(picture_id)
        logging.info("Creating at %s %s", self.position, self.angle)

        self.client_base = client.ClientBase(self)
        
        self.avatars = {}
        
    def init_network(self):
        self.client_base.init_network("picture")
        
    def load_scene(self, start_loc):
        pass
        
    def get_position(self):
        return self.position

    def client_hello(self, message):
        client_id = message["id"]
        if message["type"] == "visitor":
            self.avatars[client_id] = euclid.Vector3(*message["pos"])
    
    def client_info(self, message):
        client_id = message["id"]
        if client_id in self.avatars:
            self.avatars[client_id] = euclid.Vector3(*message["pos"])
    
    def client_bye(self, client_id):
        try:
            del self.avatars[client_id]
        except KeyError:
            pass
    
    def index_hello_hook(self, message):
        message["type"] = "picture"

    def block_hello_hook(self, message):
        message["pos"] = client.client_to_serv(self.position)
    
    def aura_hello_hook(self, message):
        logging.debug("aura_hello_hook")
        message["type"] = "picture"
        message["pos"] = self.position
        message["rot"] = self.angle
        message.update(self.picture_info)
        
    def broadcast_message(self):        
        vec1 = euclid.Vector3(*self.position)
        
        for client_id, pos in self.avatars.items():
            if (vec1 - pos).magnitude_squared() < config.nimbus_size ** 2:
                self.client_base.send_message(client_id, self.position, self.message)

if __name__ == '__main__':
    logging.basicConfig(format="%(levelname)s PICTURE %(asctime)-15s %(message)s" , level=logging.DEBUG)
    logging.info("Starting")

    _context = Context()
    _context.init_network()
    
    while True:
        current_time = time.time()
            
        if current_time - last_update_time > 1.0:
            #_context.update_network(0.)
            _context.broadcast_message()
            last_update_time = current_time

        asyncore.loop(use_poll=True, timeout=1, count=1)